/*
 * @(#)AbstractTemplateDirectiveModel.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.result.template.directive;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.*;

/**
 * {@link TemplateModel}을 unwrapping 하는 method만 구현된 추상 클래스.
 *
 * @author Web Platform Development Team
 */
public abstract class AbstractTemplateDirectiveModel implements TemplateDirectiveModel {
    Log log = LogFactory.getLog(AbstractTemplateDirectiveModel.class);

    /**
     * Gets the as string.
     *
     * @param object the object
     * @return the as string
     * @throws TemplateModelException the template model exception
     */
    protected String getAsString(Object object) throws TemplateModelException {
        return (object instanceof TemplateScalarModel) ? ((TemplateScalarModel)object).getAsString() : null;
    }

    /**
     * Gets the engine type.
     *
     * @param object the object
     * @return the engine type
     * @throws TemplateModelException the template model exception
     */
    protected String getEngineType(Object object) throws TemplateModelException {
        return (object instanceof TemplateScalarModel) ? ((TemplateScalarModel)object).getAsString() : "javascript";
    }

    /**
     * Gets the as integer.
     *
     * @param object the object
     * @return the as integer
     * @throws TemplateModelException the template model exception
     */
    protected Integer getAsInteger(Object object) throws TemplateModelException {
    	if (object instanceof TemplateNumberModel) {
    		return ((TemplateNumberModel)object).getAsNumber().intValue();
    	} else if (object instanceof SimpleScalar) {
    		return Integer.valueOf(((SimpleScalar) object).getAsString());
    	} else {
    		return null;
    	}
    }

    /**
     * Gets the as boolean.
     *
     * @param object the object
     * @return the as boolean
     * @throws TemplateModelException the template model exception
     */
    protected Boolean getAsBoolean(Object object) throws TemplateModelException {
        return (object instanceof TemplateBooleanModel) ? ((TemplateBooleanModel)object).getAsBoolean() : null;
    }

    /**
     * Gets the as list.
     *
     * @param object the object
     * @return the as list
     * @throws TemplateModelException the template model exception
     */
    protected Object getAsList(Object object) throws TemplateModelException {
        if (object instanceof TemplateSequenceModel) {
            TemplateSequenceModel sequenceModel = (TemplateSequenceModel)object;
            List<Object> list = new ArrayList<Object>();
            BeansWrapper wrapper = BeansWrapper.getDefaultInstance();

            for (int i = 0; i < sequenceModel.size(); i++) {
                list.add(wrapper.unwrap(sequenceModel.get(i)));
            }

            return list;
        }

        return null;
    }

    /**
     * Gets the as ext object.
     *
     * @param wrappedObj the wrapped obj
     * @param type       the type
     * @return the as ext object
     * @throws TemplateModelException the template model exception
     */
    protected Object getAsExtObject(Object wrappedObj, Class<?> type) throws TemplateModelException {
        Object unwappedObj = BeansWrapper.getDefaultInstance().unwrap((TemplateModel)wrappedObj, type);

        if (!type.isInstance(unwappedObj)) {
            throw new TemplateModelException("invalid type argument");
        }

        return unwappedObj;
    }
}
